package com.jrx.anytxn.transaction.service.impl;

import com.jrx.anytxn.common.data.TxnRespCode;
import com.jrx.anytxn.common.exception.TxnBizException;
import com.jrx.anytxn.common.uitl.BeanMapping;
import com.jrx.anytxn.common.uitl.BeanUtils;
import com.jrx.anytxn.number.exception.SegmentException;
import com.jrx.anytxn.number.service.ISegmentService;
import com.jrx.anytxn.param.constant.ErrorMsgConstant;
import com.jrx.anytxn.transaction.constant.TransBizConstant;
import com.jrx.anytxn.transaction.entity.*;
import com.jrx.anytxn.transaction.mapper.ext.ExtTlPaymentAllocationLogMapper;
import com.jrx.anytxn.transaction.service.IAccountService;
import com.jrx.anytxn.transaction.service.ITlPaymentAllocationLogService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * @program: anytxn-cf-transaction
 * @description: 还款分配历史表操作类
 * @author: xiaoyu.jing
 * @date: 2019-10-16 12:44
 **/
@Service
public class TlPaymentAllocationLogServiceImpl implements ITlPaymentAllocationLogService {

    private static final Logger logger = LoggerFactory.getLogger(TlPaymentAllocationLogServiceImpl.class);

    @Autowired
    private IAccountService accountService;
    @Autowired
    private ISegmentService segmentService;
    @Resource
    private ExtTlPaymentAllocationLogMapper extTlPaymentAllocationLogMapper;

    /**
     * 创建08交易账户
     *
     * @param paymentLog
     * @param loanMainInfo
     * @param bussinessDate
     * @return
     */
    @Override
    public TlPaymentAllocationLog buildTlPaymentAllocationLog(TlPaymentLog paymentLog, AmLoanMainInfo loanMainInfo, Date bussinessDate) throws TxnBizException {
        TlPaymentAllocationLog paymentAllocationLog = new TlPaymentAllocationLog();
        BeanMapping.copy(loanMainInfo, paymentAllocationLog);
        try {
            paymentAllocationLog.setId(segmentService.getId(TransBizConstant.TL_PAYMENT_ALLOCATION_LOG_ID));
        } catch (SegmentException e) {
            logger.error("主键生成错误",e);
            throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
        }
        //08会计状态，应计/非应计取默认参数，
        paymentAllocationLog.setLoanId("");//08交易账户不设置订单号
        paymentAllocationLog.setAccountingPhase(TransBizConstant.ACCOUNTING_PHASE_0);
        paymentAllocationLog.setNonAccrualsFlag(TransBizConstant.NON_ACCRUALS_FLA_0);
        paymentAllocationLog.setAccountId(accountService.getAccountId(TransBizConstant.PAYMENT_ALLOCATION_TYPE_08,
                loanMainInfo.getTenantId(),loanMainInfo.getCustomerId()));
        paymentAllocationLog.setAccountType(TransBizConstant.PAYMENT_ALLOCATION_TYPE_08);
        paymentAllocationLog.setTxnCode(TransBizConstant.TXN_CODE_PAYMENT_DETAIL);
        paymentAllocationLog.setPostingAmount(paymentLog.getAmount());
        paymentAllocationLog.setSeqNo(paymentLog.getSeqNo());
        paymentAllocationLog.setPaymentType(paymentLog.getPaymentType());
        paymentAllocationLog.setPostingDate(bussinessDate);
        paymentAllocationLog.setUpdateBy(TransBizConstant.SYS_OPRATE);
        paymentAllocationLog.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);
        //添加代偿回购判断
        if(TransBizConstant.REPAYMENT_TYPE_CMPS.equals(paymentLog.getPaymentType())||
                TransBizConstant.REPAYMENT_TYPE_CRT.equals(paymentLog.getPaymentType())){
            paymentAllocationLog.setCompensatoryFlag(TransBizConstant.COMPENSATORY_FLAG_1);
        }
        paymentAllocationLog.setCreateTime(null);
        paymentAllocationLog.setUpdateTime(null);
        paymentAllocationLog.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);
        logger.info("生成08还款交易账户paymentAllocationLog:{}", BeanUtils.toMap(paymentAllocationLog));
        return paymentAllocationLog;
    }

    /**
     * 生成09子还款交易账户
     *
     * @param totalAllocationLog
     * @param amAccountMainInfo
     * @return
     */
    @Override
    public TlPaymentAllocationLog buildTlPaymentAllocationLog(TlPaymentAllocationLog totalAllocationLog, AmAccountMainInfo amAccountMainInfo, BigDecimal realPaymentAmnt)throws TxnBizException {
        TlPaymentAllocationLog paymentAllocationLog = new TlPaymentAllocationLog();
        BeanMapping.copy(amAccountMainInfo, paymentAllocationLog);
        try {
            paymentAllocationLog.setId(segmentService.getId(TransBizConstant.TL_PAYMENT_ALLOCATION_LOG_ID));
        } catch (SegmentException e) {
            logger.error("主键生成错误",e);
            throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
        }
        paymentAllocationLog.setAccountId(accountService.getAccountId(TransBizConstant.PAYMENT_ALLOCATION_TYPE_09,
                amAccountMainInfo.getTenantId(),amAccountMainInfo.getCustomerId()));
        paymentAllocationLog.setPaymentType(totalAllocationLog.getPaymentType());
        paymentAllocationLog.setAccountType(TransBizConstant.PAYMENT_ALLOCATION_TYPE_09);
        paymentAllocationLog.setTxnCode(this.getPaymentDetailTxnAccountTxnCode(amAccountMainInfo.getTxnCode(), totalAllocationLog.getTxnCode() ,totalAllocationLog.getPaymentType(),amAccountMainInfo.getChargeoffFlag(),amAccountMainInfo.getAccountType()));
        paymentAllocationLog.setSeqNo(totalAllocationLog.getSeqNo());
        paymentAllocationLog.setPostingDate(totalAllocationLog.getPostingDate());
        paymentAllocationLog.setPostingAmount(realPaymentAmnt);
        paymentAllocationLog.setOriginalAccountId(totalAllocationLog.getAccountId());
        paymentAllocationLog.setConnectAccountType(amAccountMainInfo.getAccountType());
        paymentAllocationLog.setConnectAccountId(amAccountMainInfo.getAccountId());
        //税金大于0
        if (amAccountMainInfo.getTaxAmt()!=null && amAccountMainInfo.getTaxAmt().compareTo(BigDecimal.ZERO)>0){
            //核销时税金登记  表外还款时登记税金
            if (TransBizConstant.CHARGOFF_FLAG_1.equals(amAccountMainInfo.getChargeoffFlag())
                    || TransBizConstant.NON_ACCRUALS_FLA_1.equals(amAccountMainInfo.getNonAccrualsFlag())) {
                //因为存在部分逾期还款 所以采用 每次登记税金 = （本次还款额+已还款额）/总应还额 * 总税金 的计算法则，保证多次逾期还款后，登记税金 = 原交易账户税
                BigDecimal afterPayTaxAmt = amAccountMainInfo.getRepayAmount().add(realPaymentAmnt).multiply(amAccountMainInfo.getTaxAmt()).divide(amAccountMainInfo.getPostingAmount(), 2, BigDecimal.ROUND_HALF_UP);
                BigDecimal beforeTaxAmt = amAccountMainInfo.getRepayAmount().multiply(amAccountMainInfo.getTaxAmt()).divide(amAccountMainInfo.getPostingAmount(), 2, BigDecimal.ROUND_HALF_UP);
                BigDecimal taxAmt = afterPayTaxAmt.subtract(beforeTaxAmt).setScale(2, BigDecimal.ROUND_HALF_UP);
                paymentAllocationLog.setTaxAmt(taxAmt);
            }
        }else{
            paymentAllocationLog.setTaxAmt(BigDecimal.ZERO);
        }
        paymentAllocationLog.setLiabilityFlag(amAccountMainInfo.getLiabilityFlag());
        paymentAllocationLog.setUpdateBy(TransBizConstant.SYS_OPRATE);
        paymentAllocationLog.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);
        paymentAllocationLog.setCompensatoryFlag(totalAllocationLog.getCompensatoryFlag());
        paymentAllocationLog.setCreateTime(null);
        paymentAllocationLog.setUpdateTime(null);
        paymentAllocationLog.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);
        logger.info("生成09还款交易账户paymentAllocationLog:{}", BeanUtils.toMap(paymentAllocationLog));
        return paymentAllocationLog;
    }

    @Override
    public TlPaymentAllocationLog buildTlPaymentAllocationLog(TlLoanStagingMapping tlLoanStagingMapping, AmLoanMainInfo loanMainInfo, Date bussinessDate) throws TxnBizException {
        TlPaymentAllocationLog paymentAllocationLog = new TlPaymentAllocationLog();
        BeanMapping.copy(loanMainInfo, paymentAllocationLog);
        try {
            paymentAllocationLog.setId(segmentService.getId(TransBizConstant.TL_PAYMENT_ALLOCATION_LOG_ID));
        } catch (SegmentException e) {
            logger.error("主键生成错误",e);
            throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
        }
        //08会计状态，应计/非应计取默认参数，
        paymentAllocationLog.setLoanId("");//08交易账户不设置订单号
        paymentAllocationLog.setAccountingPhase(TransBizConstant.ACCOUNTING_PHASE_0);
        paymentAllocationLog.setNonAccrualsFlag(TransBizConstant.NON_ACCRUALS_FLA_0);
        paymentAllocationLog.setAccountId(accountService.getAccountId(TransBizConstant.PAYMENT_ALLOCATION_TYPE_08,
                loanMainInfo.getTenantId(),loanMainInfo.getCustomerId()));
        paymentAllocationLog.setAccountType(TransBizConstant.PAYMENT_ALLOCATION_TYPE_08);
        paymentAllocationLog.setTxnCode(TransBizConstant.TXN_CODE_PAYMENT_DETAIL);
        paymentAllocationLog.setPostingAmount(tlLoanStagingMapping.getLoanAmount());
        paymentAllocationLog.setSeqNo(tlLoanStagingMapping.getStagingLoanId());
        paymentAllocationLog.setPaymentType(TransBizConstant.REPAYMENT_TYPE_STAGING);
        paymentAllocationLog.setPostingDate(bussinessDate);
        paymentAllocationLog.setUpdateBy(TransBizConstant.SYS_OPRATE);
        paymentAllocationLog.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);
        paymentAllocationLog.setCreateTime(null);
        paymentAllocationLog.setUpdateTime(null);
        paymentAllocationLog.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);
        logger.info("生成08还款交易账户paymentAllocationLog:{}", BeanUtils.toMap(paymentAllocationLog));
        return paymentAllocationLog;
    }

    @Override
    public TlPaymentAllocationLog buildTlPaymentAllocationLog(TlWaivePaymentLog waivePaymentLog, AmLoanMainInfo loanMainInfo, Date bussinessDate) throws TxnBizException {
        TlPaymentAllocationLog paymentAllocationLog = new TlPaymentAllocationLog();
        BeanMapping.copy(loanMainInfo, paymentAllocationLog);
        try {
            paymentAllocationLog.setId(segmentService.getId(TransBizConstant.TL_PAYMENT_ALLOCATION_LOG_ID));
        } catch (SegmentException e) {
            logger.error("主键生成错误",e);
            throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
        }
        //08会计状态，应计/非应计取默认参数，
        paymentAllocationLog.setLoanId("");//08交易账户不设置订单号
        paymentAllocationLog.setAccountingPhase(TransBizConstant.ACCOUNTING_PHASE_0);
        paymentAllocationLog.setNonAccrualsFlag(TransBizConstant.NON_ACCRUALS_FLA_0);
        paymentAllocationLog.setAccountId(accountService.getAccountId(TransBizConstant.PAYMENT_ALLOCATION_TYPE_08,
                loanMainInfo.getTenantId(),loanMainInfo.getCustomerId()));
        paymentAllocationLog.setAccountType(TransBizConstant.PAYMENT_ALLOCATION_TYPE_08);
        paymentAllocationLog.setTxnCode(TransBizConstant.TXN_CODE_PAYMENT_DETAIL);
        paymentAllocationLog.setPostingAmount(waivePaymentLog.getAmount());
        paymentAllocationLog.setSeqNo(waivePaymentLog.getSeqNo());
        paymentAllocationLog.setPaymentType(waivePaymentLog.getPaymentType());
        paymentAllocationLog.setPostingDate(bussinessDate);
        paymentAllocationLog.setUpdateBy(TransBizConstant.SYS_OPRATE);
        paymentAllocationLog.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);
        paymentAllocationLog.setCreateTime(null);
        paymentAllocationLog.setUpdateTime(null);
        logger.info("生成08还款交易账户paymentAllocationLog:{}", BeanUtils.toMap(paymentAllocationLog));
        return paymentAllocationLog;
    }

    @Override
    public List<TlPaymentAllocationLog> findCustLog(String loanId, String seqNo, String customerId, String tenantId) {
        return extTlPaymentAllocationLogMapper.findCustLog(loanId,seqNo,customerId,tenantId);
    }

    /**
     * 09还款交易码生成
     *
     * @param origleTxnCode
     * @param payMentCode
     * @param paymentType
     * @param chargeoffFlag
     * @return
     */
    @Override
    public String getPaymentDetailTxnAccountTxnCode(String origleTxnCode, String payMentCode , String paymentType, String chargeoffFlag,String accountType) {
        //账单分期交易码
        if(TransBizConstant.REPAYMENT_TYPE_STAGING.equals(paymentType)){
            if(TransBizConstant.TXN_CODE_INST.equals(origleTxnCode)){
                return TransBizConstant.TXN_CODE_STAGING_PRINCIPAL;
            }else if(TransBizConstant.TXN_CODE_INST_INTR.equals(origleTxnCode)){
                return TransBizConstant.TXN_CODE_STAGING_INTR;
            }else if(TransBizConstant.TXN_CODE_INST_PEN_INTR.equals(origleTxnCode)){
                return TransBizConstant.TXN_CODE_STAGING_PEN_INTR;
            }else if(TransBizConstant.TXN_CODE_INST_ONECE_FEE.equals(origleTxnCode)){
                return TransBizConstant.TXN_CODE_STAGING_ONECE_FEE;
            }else if(TransBizConstant.TXN_CODE_INST_FEE.equals(origleTxnCode)){
                return TransBizConstant.TXN_CODE_STAGING_FEE;
            }else if(TransBizConstant.TXN_CODE_INST_COMP_INTR.equals(origleTxnCode)){
                return TransBizConstant.TXN_CODE_STAGING_COMP_INTR;
            }
        }

        if (TransBizConstant.CHARGOFF_FLAG_1.equals(chargeoffFlag)){
            switch (accountType){
                case TransBizConstant.ACCOUNT_TYPE_06:
                    return TransBizConstant.TXN_CHARGEOFF_PAY_CODE_PRINCIPAL;
                case TransBizConstant.ACCOUNT_TYPE_03:
                    return TransBizConstant.TXN_CHARGEOFF_PAY_CODE_FEE;
                case TransBizConstant.ACCOUNT_TYPE_04:
                    return TransBizConstant.TXN_CHARGEOFF_PAY_CODE_INTR;
                case TransBizConstant.ACCOUNT_TYPE_11:
                    return TransBizConstant.TXN_CHARGEOFF_PAY_CODE_PEN_INTR;
                case TransBizConstant.ACCOUNT_TYPE_12:
                    return TransBizConstant.TXN_CHARGEOFF_PAY_CODE_COMP_INTR;
            }
        }

        //还款交易的前二位
        String payTxncode = StringUtils.substring(payMentCode, 0, 2);
        StringBuilder str = new StringBuilder(origleTxnCode);
        //原始交易的第二位
        String firtString = str.substring(1, 2);
        //后三位
        String substring = str.substring(2);
        StringBuilder buffer = new StringBuilder(substring);
        StringBuilder replace = buffer.replace(2, 3, firtString);

        String txnCode = payTxncode + replace;

        return txnCode;
    }
}
